bitkeeper revision 1.1244 (42308dfaWqh7O5QB-sS9WJ1R4LYoEA)
authorrneugeba@wyvis.research.intel-research.net <rneugeba@wyvis.research.intel-research.net>
Thu, 10 Mar 2005 18:12:10 +0000 (18:12 +0000)
committerrneugeba@wyvis.research.intel-research.net <rneugeba@wyvis.research.intel-research.net>
Thu, 10 Mar 2005 18:12:10 +0000 (18:12 +0000)
various hacks for batching mode and stats gathering

Signed-off-by: michael.fetterman@cl.cam.ac.uk
.rootkeys
linux-2.6.10-xen-sparse/arch/xen/Kconfig
linux-2.6.10-xen-sparse/arch/xen/i386/kernel/Makefile
linux-2.6.10-xen-sparse/arch/xen/i386/kernel/entry.S
linux-2.6.10-xen-sparse/arch/xen/i386/kernel/syscall_stats.c [new file with mode: 0644]
linux-2.6.10-xen-sparse/arch/xen/i386/mm/hypervisor.c
linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h
linux-2.6.10-xen-sparse/mm/memory.c
tools/misc/Makefile
tools/misc/cpuperf/cpuperf.c
tools/misc/xc_shadow.c [new file with mode: 0644]

index b7b65f0953736ca88186a9aa10d4477f306eb7d6..e4a647515151455d27745202725f459f3f66d6ec 100644 (file)
--- a/.rootkeys
+++ b/.rootkeys
 40f56238nWMQg7CKbyTy0KJNvCzbtg linux-2.6.10-xen-sparse/arch/xen/i386/kernel/signal.c
 41811cac4lkCB-fHir6CcxuEJ2pGsQ linux-2.6.10-xen-sparse/arch/xen/i386/kernel/smp.c
 41811ca9mbGpqBrZVrUGEiv8CTV3ng linux-2.6.10-xen-sparse/arch/xen/i386/kernel/smpboot.c
+42308df8u332Gs7XX-jX4gsfFU2zOQ linux-2.6.10-xen-sparse/arch/xen/i386/kernel/syscall_stats.c
 40f56238qVGkpO_ycnQA8k03kQzAgA linux-2.6.10-xen-sparse/arch/xen/i386/kernel/time.c
 40f56238NzTgeO63RGoxHrW5NQeO3Q linux-2.6.10-xen-sparse/arch/xen/i386/kernel/timers/Makefile
 40f56238BMqG5PuSHufpjbvp_helBw linux-2.6.10-xen-sparse/arch/xen/i386/kernel/timers/timer_tsc.c
 40c9c469kT0H9COWzA4XzPBjWK0WsA tools/misc/netfix
 4022a73cEKvrYe_DVZW2JlAxobg9wg tools/misc/nsplitd/Makefile
 4022a73cKms4Oq030x2JBzUB426lAQ tools/misc/nsplitd/nsplitd.c
+42308df9dv_ZuP49nNPIROEMQ3F_LA tools/misc/xc_shadow.c
 3f5ef5a2ir1kVAthS14Dc5QIRCEFWg tools/misc/xen-clone
 3f5ef5a2dTZP0nnsFoeq2jRf3mWDDg tools/misc/xen-clone.README
 405eedf6_nnNhFQ1I85lhCkLK6jFGA tools/misc/xencons
index 2a8c5f200f97530c01bfe11426e4dee0c49344f2..47e508cdc12c80bc51fc9e67bf1acbdd65d62878 100644 (file)
@@ -115,9 +115,38 @@ config XEN_BLKDEV_TAP
          space.  Odds are that you want to say N here.
 
 config XEN_WRITABLE_PAGETABLES
-       bool
+       bool "writable page tables"
        default y
 
+config XEN_SYSCALL_STATS
+       bool "system call statistics"
+       default n
+
+config XEN_DEBUG_NO_MMU_BATCHING
+       bool "Disables batching on MMU updates"
+       default n
+    help
+      This does a hypercall per PTE update
+      we only use this for benchmarking
+      enable only if you know what you are doing
+
+config XEN_BATCH_MODE1
+       bool "A variant of writable pagetable using the batch interface"
+       default n
+    help
+      default is no batching and minor mods for some batching
+      we only use this for benchmarking
+      enable only if you know what you are doing
+
+config XEN_BATCH_MODE2
+       bool "forward port of 2.4 batching"
+       default n
+    help
+      default is batching + flushes where 2.4 had them
+      we only use this for benchmarking
+      enable only if you know what you are doing
+
+
 config XEN_SCRUB_PAGES
        bool "Scrub memory before freeing it to Xen"
        default y
index 15429584648b1f6d29b595a565a410116c164699..13be9fb3973dd2b109efc81654ed434795ef8a4d 100644 (file)
@@ -43,6 +43,8 @@ c-obj-$(CONFIG_HPET_TIMER)    += time_hpet.o
 c-obj-$(CONFIG_EFI)            += efi.o efi_stub.o
 c-obj-$(CONFIG_EARLY_PRINTK)   += early_printk.o
 
+c-obj-$(CONFIG_XEN_SYSCALL_STATS) += syscall_stats.o
+
 EXTRA_AFLAGS   := -traditional
 
 c-obj-$(CONFIG_SCx200)         += scx200.o
index db26c6a44079936d89a0811d5a76fc23e73e7022..80fbaa5633d9c2a749927a5394e437d0b9700617 100644 (file)
@@ -280,7 +280,10 @@ sysenter_past_esp:
        jnz syscall_trace_entry
        cmpl $(nr_syscalls), %eax
        jae syscall_badsys
-       call *sys_call_table(,%eax,4)
+#ifdef CONFIG_XEN_SYSCALL_STATS
+    lock incl syscall_stats(,%eax,4)
+#endif
+    call *sys_call_table(,%eax,4)
        movl %eax,EAX(%esp)
        cli
        movl TI_flags(%ebp), %ecx
@@ -305,7 +308,10 @@ ENTRY(system_call)
        cmpl $(nr_syscalls), %eax
        jae syscall_badsys
 syscall_call:
-       call *sys_call_table(,%eax,4)
+#ifdef CONFIG_XEN_SYSCALL_STATS
+    lock incl syscall_stats(,%eax,4)
+#endif
+    call *sys_call_table(,%eax,4)
        movl %eax,EAX(%esp)             # store the return value
 syscall_exit:
        XEN_BLOCK_EVENTS(%esi)          # make sure we don't miss an interrupt
diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/syscall_stats.c b/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/syscall_stats.c
new file mode 100644 (file)
index 0000000..e614a31
--- /dev/null
@@ -0,0 +1,91 @@
+/* -*-  Mode:C; c-basic-offset:4; tab-width:4 -*-
+ ****************************************************************************
+ * (C) 2005 - Rolf Neugebauer - Intel Research Cambridge
+ ****************************************************************************
+ *
+ *        File: syscall_stats.c
+ *      Author: Rolf Neugebauer (rolf.neugebauer@intel.com)
+ *        Date: Mar 2005
+ * 
+ * Description: add a proc interface to get per system call stats
+ */
+
+
+#include <linux/config.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <asm/unistd.h>
+
+unsigned long syscall_stats[NR_syscalls];
+static unsigned char foobar[4];
+
+/* a write just resests the counter */
+static ssize_t syscall_write(struct file *f, const  char *data,
+                             size_t size, loff_t  *pos)
+{
+    printk("resetting syscall stats\n");
+    memset(&syscall_stats, 0, sizeof(syscall_stats));
+    return size;
+}
+
+static int show_syscall(struct seq_file *m, void *v)
+{
+    int i;
+    for ( i=0; i<NR_syscalls; i++ )
+    {
+        seq_printf(m, "%lu ", syscall_stats[i]);
+    }
+    seq_printf(m, "\n");
+    return 0;
+}
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+    return *pos == 0 ? foobar : NULL;
+}
+
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+    ++*pos;
+    return c_start(m, pos);
+}
+
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+
+static struct seq_operations syscall_op = {
+    start:  c_start,
+    next:   c_next,
+    stop:   c_stop,
+    show:   show_syscall,
+};
+
+static int syscall_open(struct inode *inode, struct file *file)
+{
+    return seq_open(file, &syscall_op);
+}
+
+static struct file_operations proc_syscall_operations = {
+    open:           syscall_open,
+    read:           seq_read,
+    write:          syscall_write,
+    llseek:         seq_lseek,
+    release:        seq_release,
+};
+
+
+static struct proc_dir_entry *entry;
+
+static int __init syscall_stats_init(void)
+{
+    printk("Initialising syscall stats.\n");
+
+    entry = create_proc_entry("syscalls", 0777, NULL);
+    if (entry)
+        entry->proc_fops = &proc_syscall_operations;
+    else
+        printk("Unable to create /proc/syscalls.\n");
+    return 0;
+}
+subsys_initcall(syscall_stats_init);
index 9068960f051e541524e0773eed185cf8099428f9..b9786ff8f458e48c506c32d621c57895acfa155f 100644 (file)
@@ -133,6 +133,9 @@ void queue_l1_entry_update(pte_t *ptr, unsigned long val)
     per_cpu(update_queue[idx], cpu).ptr = virt_to_machine(ptr);
     per_cpu(update_queue[idx], cpu).val = val;
     increment_index();
+#ifdef CONFIG_XEN_DEBUG_NO_MMU_BATCHING
+    __flush_page_update_queue();
+#endif
     spin_unlock_irqrestore(&update_lock, flags);
 }
 
index 3abd3ce14a56a5417b1092e4caf9a32802cb39b5..8c1a53ee75563b7686c244d7a8f41e5d302a4023 100644 (file)
@@ -36,7 +36,16 @@ do { \
 #endif
 #define set_pte_atomic(pteptr, pteval) set_pte(pteptr, pteval)
 #else
+#if defined(CONFIG_XEN_DEBUG_NO_MMU_BATCHING)
+#define set_pte(pteptr, pteval)\
+    set_pte_batched(pteptr, pteval)
+#elif defined(CONFIG_XEN_BATCH_MODE)
+#define set_pte(pteptr, pteval)({\
+    set_pte_batched(pteptr, pteval);\
+    _flush_page_update_queue();})
+#else
 #define set_pte(pteptr, pteval) (*(pteptr) = pteval)
+#endif
 #define set_pte_atomic(pteptr, pteval) set_pte(pteptr,pteval)
 #endif
 /*
index cd10d79d94cd7bc247f7ffeb491700333b995ccf..67ad00662183299c4e9a4a711a57f0c4bff3f25e 100644 (file)
@@ -218,6 +218,11 @@ out:
  * dst->page_table_lock is held on entry and exit,
  * but may be dropped within pmd_alloc() and pte_alloc_map().
  */
+#ifdef CONFIG_XEN_BATCH_MODE1
+#undef set_pte
+#define set_pte(pteptr, pteval)\
+    set_pte_batched(pteptr, pteval);
+#endif
 int copy_page_range(struct mm_struct *dst, struct mm_struct *src,
                        struct vm_area_struct *vma)
 {
@@ -354,8 +359,11 @@ cont_copy_pte_range_noset:
                        cond_resched_lock(&dst->page_table_lock);
 cont_copy_pmd_range:
                        src_pmd++;
-                       dst_pmd++;
+                       dst_pmd++;            
                } while ((unsigned long)src_pmd & PMD_TABLE_MASK);
+#ifdef CONFIG_XEN_BATCH_MODE1
+        _flush_page_update_queue();
+#endif
        }
 out_unlock:
        spin_unlock(&src->page_table_lock);
@@ -445,9 +453,19 @@ static void zap_pte_range(struct mmu_gather *tlb,
                        free_swap_and_cache(pte_to_swp_entry(pte));
                pte_clear(ptep);
        }
+#ifdef CONFIG_XEN_BATCH_MODE1
+    _flush_page_update_queue();
+#endif
        pte_unmap(ptep-1);
 }
 
+#ifdef CONFIG_XEN_BATCH_MODE1
+#undef set_pte
+#define set_pte(pteptr, pteval)\
+    set_pte_batched(pteptr, pteval);\
+    _flush_page_update_queue()
+#endif
+
 static void zap_pmd_range(struct mmu_gather *tlb,
                pgd_t * dir, unsigned long address,
                unsigned long size, struct zap_details *details)
@@ -839,6 +857,11 @@ out:
 
 EXPORT_SYMBOL(get_user_pages);
 
+#ifdef CONFIG_XEN_BATCH_MODE1
+#undef set_pte
+#define set_pte(pteptr, pteval)\
+    set_pte_batched(pteptr, pteval);
+#endif
 static void zeromap_pte_range(pte_t * pte, unsigned long address,
                                      unsigned long size, pgprot_t prot)
 {
@@ -855,7 +878,18 @@ static void zeromap_pte_range(pte_t * pte, unsigned long address,
                address += PAGE_SIZE;
                pte++;
        } while (address && (address < end));
+
+#ifdef CONFIG_XEN_BATCH_MODE1
+    _flush_page_update_queue();
+#endif
+
 }
+#ifdef CONFIG_XEN_BATCH_MODE1
+#undef set_pte
+#define set_pte(pteptr, pteval)\
+    set_pte_batched(pteptr, pteval);\
+    _flush_page_update_queue()
+#endif
 
 static inline int zeromap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address,
                                     unsigned long size, pgprot_t prot)
@@ -917,6 +951,11 @@ int zeromap_page_range(struct vm_area_struct *vma, unsigned long address, unsign
  * mappings are removed. any references to nonexistent pages results
  * in null mappings (currently treated as "copy-on-access")
  */
+#ifdef CONFIG_XEN_BATCH_MODE1
+#undef set_pte
+#define set_pte(pteptr, pteval)\
+    set_pte_batched(pteptr, pteval);
+#endif
 static inline void remap_pte_range(pte_t * pte, unsigned long address, unsigned long size,
        unsigned long pfn, pgprot_t prot)
 {
@@ -934,7 +973,16 @@ static inline void remap_pte_range(pte_t * pte, unsigned long address, unsigned
                pfn++;
                pte++;
        } while (address && (address < end));
+#ifdef CONFIG_XEN_BATCH_MODE1
+    _flush_page_update_queue();
+#endif
 }
+#ifdef CONFIG_XEN_BATCH_MODE1
+#undef set_pte
+#define set_pte(pteptr, pteval)\
+    set_pte_batched(pteptr, pteval);\
+    _flush_page_update_queue()
+#endif
 
 static inline int remap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address, unsigned long size,
        unsigned long pfn, pgprot_t prot)
index 39b38c25c11ce7f6ed062de4ed3b4bec9f89fe8d..3b533e5dc42dba61387ab67627b07c84cfef08d3 100644 (file)
@@ -14,7 +14,7 @@ CFLAGS   += $(INCLUDES)
 
 HDRS     = $(wildcard *.h)
 
-TARGETS  = xenperf
+TARGETS  = xenperf xc_shadow
 
 INSTALL_BIN  = $(TARGETS) xencons
 INSTALL_SBIN = netfix xm xend xensv xenperf
index 4e4dbb0665d3c0989ea6101aece46f8fc6fc9b9d..093cde556d43d6397873e361fddc8051c769394a 100644 (file)
@@ -246,7 +246,7 @@ int main(int argc, char **argv)
         while((cpu_mask&1)) {
             int i;
             for (i=0x300;i<0x312;i++) {
-                printf("%010llx ",cpus_rdmsr( cpu_mask, i ) );
+                printf("%010llu ",cpus_rdmsr( cpu_mask, i ) );
             }
             printf("\n");
             cpu_mask>>=1;
diff --git a/tools/misc/xc_shadow.c b/tools/misc/xc_shadow.c
new file mode 100644 (file)
index 0000000..ba21a34
--- /dev/null
@@ -0,0 +1,70 @@
+/* -*-  Mode:C; c-basic-offset:4; tab-width:4 -*-
+ ****************************************************************************
+ * (C) 2005 - Rolf Neugebauer - Intel Research Cambridge
+ ****************************************************************************
+ *
+ *        File: xc_shadow.c
+ *      Author: Rolf Neugebauer (rolf.neugebauer@intel.com)
+ *        Date: Mar 2005
+ * 
+ * Description: 
+ */
+
+
+#include <xc.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <string.h>
+
+void usage()
+{
+    printf("xc_shadow: -[0|1|2]\n");
+    printf("    set shadow mode\n");
+    exit(0);
+}
+
+int main(int argc, char *argv[])
+{
+    int xc_handle;
+    int mode;
+
+    if ( argc > 1 )
+    {
+        char *p = argv[1];
+        if (*p++ == '-') {
+            if (*p == '1')
+                mode = 1;
+            else if (*p == '2')
+                mode = 2;
+            else if (*p == '0')
+                mode = 0;
+            else
+                usage();
+        } else
+            usage();
+    } 
+    else
+        usage();
+
+    if ( (xc_handle = xc_interface_open()) == -1 )
+    {
+        fprintf(stderr, "Error opening xc interface: %d (%s)\n",
+                errno, strerror(errno));
+        return 1;
+    }
+
+    if ( xc_shadow_control(xc_handle,
+                           0,
+                           mode, 
+                           NULL,
+                           0,
+                           NULL) < 0 )
+    {    
+        fprintf(stderr, "Error reseting performance counters: %d (%s)\n",
+                errno, strerror(errno));
+        return 1;
+    }
+    return 0;
+}